package com.itcoon.cloud.framework.utils;

import com.itcoon.cloud.framework.constants.CommonCoreConstants;
import com.itcoon.cloud.framework.model.SuFunction;

import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class SuFunctionUtils {

    private static Map<Class<?>, SerializedLambda> CLASS_LAMDBA_CACHE = new ConcurrentHashMap<>();

    public static <R, V> String getAttributeName(SuFunction<R, V> attribute){
        SerializedLambda serializedLambda = getSerializedLambda(attribute);
        String implMethodName = serializedLambda.getImplMethodName();
        if(!implMethodName.startsWith(CommonCoreConstants.GETTER_PREFIX)){
            throw new RuntimeException("Invalid attribute, it must be start with 'get'");
        }
        return implMethodName.substring(3,4).toLowerCase() + implMethodName.substring(4);
    }


    private  static SerializedLambda getSerializedLambda(Serializable fn) {
        SerializedLambda lambda = CLASS_LAMDBA_CACHE.get(fn.getClass());
        if(lambda == null) {
            try {
                Method method = fn.getClass().getDeclaredMethod("writeReplace");
                method.setAccessible(Boolean.TRUE);
                lambda = (SerializedLambda) method.invoke(fn);
                CLASS_LAMDBA_CACHE.put(fn.getClass(), lambda);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return lambda;
    }
}
